<?php
namespace Core;

use DI\ContainerBuilder;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;

class BeanFactory
{
    private static $env = []; //env 配置文件
    private static $cotainer; //ioc 容器

    public static function init() //初始化函数

    {
        self::$env = parse_ini_file(ROOT_PAHT . "/env");
        $builder = new ContainerBuilder(); //初始化容器Builder
        $builder->useAnnotations(true); //启用注解，主要是用它的Inject注解
        self::$cotainer = $builder->build(); //容器初始化
        self::ScanBeans(); //扫描
    }
//获取env文件中的配置内容
    private static function getEnv(string $key, string $default = "")
    {
        if (isset(self::$env[$key])) {
            return self::$env[$key];
        }

        return $default;
    }
    public static function getBean($name)
    {
        return self::$cotainer->get($name);
    }
    public static function ScanBeans()
    {
        //读取注解 对应的handler
        $anno_handlers = require_once ROOT_PAHT . "/core/annotations/AnnotationHandlers.php";
        /*
            array(2) {
                ["Core\annotations\Bean"]=>
                    object(Closure)#10 (1) {
                        ["parameter"]=>
                            array(2) {
                                ["$instance"]=>
                                    string(10) "<required>"
                                ["$container"]=>
                                    string(10) "<required>"
                            }
                    }
                ["Core\annotations\Value"]=>
                    object(Closure)#11 (0) {
                    }
}
        */
        //加载类文件
        $scan_dir = self::getEnv("scan_dir", ROOT_PAHT . "/app"); //扫描路径
        $scan_root_namespace = self::getEnv("scan_root_namespace", "App\\"); //扫描的 namespace
        $files = glob($scan_dir . "/*.php");
        foreach ($files as $file) {
            require_once $file;
        }
        // var_dump(get_declared_classes());exit;
        //Bean注解的类实例化到容器中
        $reader = new AnnotationReader();
        // AnnotationRegistry::registerAutoloadNamespace("Core\annotations");
        AnnotationRegistry::registerLoader('class_exists');

        foreach (get_declared_classes() as $class) {
            if (strstr($class, $scan_root_namespace)) {
                $ref_class = new \ReflectionClass($class); //目标类的反射对象
                //   var_dump($ref_class);exit;
                /*
                object(ReflectionClass)#18 (1) {
                ["name"]=>
                string(30) "App\controllers\UserController"
                }
                 */
                $class_annos = $reader->getClassAnnotations($ref_class); //获取所有Bean类注解
                //   var_dump($class_annos);exit;
                /*
                array(1) {
                [0]=>
                object(Core\annotations\Bean)#22 (0) {
                }
                }
                 */
                /////下方是处理 类注解
                foreach ($class_annos as $class_anno) {
                    // var_dump(get_class($class_anno));exit;
                    $handler = $anno_handlers[get_class($class_anno)]; //获取handler处理过程
                    // var_dump($anno_handlers);exit;
                    /*
                        array(2) {
                            ["Core\annotations\Bean"]=>
                                object(Closure)#10 (1) {
                                    ["parameter"]=>
                                        array(2) {
                                            ["$instance"]=>
                                                string(10) "<required>"
                                            ["$container"]=>
                                                string(10) "<required>"
                                        }
                                }
                            ["Core\annotations\Value"]=>
                                object(Closure)#11 (0) {
                                }
                        }
                    */
                    // var_dump(self::$cotainer->get($ref_class->getName()));exit;
                    /*
                        object(App\controllers\UserController)#29 (1) {
                            ["version"]=>
                                string(3) "1.0"
                        }
                    */
                    // self::$cotainer->get($ref_class->getName());
                    // var_dump(self::$cotainer);exit;
                    //类实例加载到容器,
                    //self::$cotainer->get会加载命名空间类名
                    //handler加载是类名
                    //App\controllers\UserController=>object
                    //UserController=>object
                    $handler(self::$cotainer->get($ref_class->getName()), self::$cotainer); //执行处理
                    // var_dump(self::$cotainer);exit;
                }
            }
        }

    }

}
